﻿using System;
using System.Collections.Generic;
using System.Web.Routing;
using ManagedUIFlow.Infrastructure.Flows;
using ManagedUIFlow.Model;

namespace ManagedUIFlow.Infrastructure.Commands
{
    public class DefaultCommandFactory : ICommandFactory {

        private CommandBuilder _commandBuilder;

        public RequestContext RequestContext {
            get;
            set;
        }

        internal CommandBuilder CommandBuilder
        {
            get
            {
                return _commandBuilder ?? CommandBuilder.Current;
            }
            set
            {
                _commandBuilder = value;
            }
        }

        public virtual ICommand CreateCommand(RequestContext requestContext, ManagedFlow flow) {
            if (requestContext == null) throw new ArgumentNullException("requestContext");
            if (flow == null) throw new ArgumentNullException("flow");

            if (string.IsNullOrEmpty(flow.CurrentNavigation))
                return new EndFlow(requestContext);

            foreach (var flow1 in Flows)
                if (flow1.Name == flow.Name)
                    foreach (var navigation in flow1.Navigations)
                        if (navigation.Name == flow.CurrentNavigation || (string.IsNullOrEmpty(flow.CurrentNavigation) && navigation.Name == flow1.StartupNavigation))
                            switch (navigation.NavigationType)
                            {
                                case NavigationType.ControllerAction:
                                    return new FlowAction(requestContext);
                                case NavigationType.SubFlow:
                                    return new SubFlow(requestContext);                                
                                default:
                                    return new FlowView(requestContext);
                            }

            return null;
        }

        public virtual void ReleaseCommand(ICommand command) {
            var disposable = command as IDisposable;
            if (disposable != null) {
                disposable.Dispose();
            }
        }

        private IEnumerable<Flow> _flows;
        public IEnumerable<Flow> Flows
        {
            get
            {
                if (_flows == null)
                    _flows = XmlFlowFactory.Flows;

                return _flows;
            }
            set { _flows = value; }
        }
    }
}